/**
 * @author Da Mu
 * @version v1.2.1.beta.1
 * @mail 317782199@qq.com
 */
import {
    WebSocketGateway,
    WebSocketServer,
    SubscribeMessage,
    MessageBody,
    ConnectedSocket,
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { TemplateApiGameRoom } from '../TemplateApiGameSocketRoom/TemplateApiGame.room';
import { TemplateApiRedisService } from '../TemplateApiPlugService/TemplateApiRedis.service';
import { forwardRef, Inject, NotFoundException } from '@nestjs/common';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger as WinstonLogger } from 'winston';


@WebSocketGateway({
    path: '/api/v1/ws',
    cors: {
        origin: '*'
    },
})
export class TemplateApiChatGateway {
    @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: WinstonLogger
    constructor(
        /**
         * @description Solving the problem of dependency injection and mutual cyclic dependencies
         */
        @Inject(forwardRef(() => TemplateApiGameRoom))
        private readonly gameRoom: TemplateApiGameRoom,
        private readonly redis: TemplateApiRedisService
    ) { };
    @WebSocketServer()
    server: Server;

    async handleConnection(@ConnectedSocket() client: Socket) {
        console.log(`客户端已连接: ${client.id}`);
        this.gameRoom.NumberOfOnlinePlayer = await this.redis.incr('MONumber_of_online_player');
        if (this.gameRoom.NumberOfOnlinePlayer === 1) {
            await this.redis.expire('MONumber_of_online_player', 86400);
        };
        this.logger.info({ event: 'socketConnection', clientId: `${client.id}` });
    };

    async handleDisconnect(@ConnectedSocket() client: Socket) {
        console.log(`客户端已断开连接: ${client.id}`);
        let count = await this.redis.decr('MONumber_of_online_player');

        if (count < 0) {
            count = 0;
            await this.redis.set('MONumber_of_online_player', 0);
        };

        this.gameRoom.NumberOfOnlinePlayer = count;
        this.logger.info({ event: 'socketDisconnect', clientId: `${client.id}` });
    };

    /**
     * 
     * @param client
     * @param data
     * @description Multiplayer online Number of online player
     */
    @SubscribeMessage('MOpublicGameSceneWorldNOOP')
    handleMONOOP(
        @ConnectedSocket() client: Socket,
        @MessageBody() data: string,
    ): void {
        console.log(`收到消息: ${client.id}: ${data}`);

        if (data === 'NOOP') {
            this.gameRoom.client = client;
            this.gameRoom.server = this.server;
            this.gameRoom.publicGameSceneWorldNOOP();
        };

    };

    /**
     * 
     * @param client 
     * @param data 
     * @description Multiplayer online chat
     */
    @SubscribeMessage('MOpublicGameSceneWorldPC')
    handleMOPC(
        @ConnectedSocket() client: Socket,
        @MessageBody() data: any
    ): void {

        console.log(`收到消息: ${client.id}: ${data}`);
        let body: any;
        try {
            body = JSON.parse(data);
        } catch (error) {
            body = data;
        };

        if (body.type === 'playerChat') {
            this.gameRoom.client = client;
            this.gameRoom.publicGameSceneWorldPC(body.body);
        };

    };

    /**
     * 
     * @param client 
     * @param data 
     * @description leave room / del
     */
    @SubscribeMessage('MOpublicGameSceneWorldLeaveDel')
    handleGMOLeave(
        @ConnectedSocket() client: Socket,
        @MessageBody() data: any
    ): void {

        console.log(`收到消息: ${client.id}: ${data}`);
        let body: any;
        try {
            body = JSON.parse(data);
        } catch (error) {
            body = data;
        };

        if (body.type === 'leave') {
            this.gameRoom.client = client;
            this.gameRoom.publicGameSceneWorldDisRoom(body);
        };

        if (body.type === 'del') {
            this.redis.delete(['MONumber_of_online_player']);
        };

    };

};